#include <game/CameraDefinition.h>
#include <game/ResourceReferenceDefinition.h>

#include <Gluck.h>
#include <xml/Stream.h>
#include <resource/Manager.h>
#include <lib3d/node/Node.h>
#include <lib3d/node/Camera.h>
#include <lib3d/node/Factory.h>

using namespace liba::lib3d;

ARELLO_GAME_NAMESPACE_DECL_START

CameraDefinition::CameraDefinition()
	: sceneRoot(0)
{
}

CameraDefinition::~CameraDefinition()
{
}

void CameraDefinition::SetSceneRoot(liba::lib3d::node::Node* sceneRoot)
{
	this->sceneRoot = sceneRoot;
}

bool CameraDefinition::on_node(xml::Provider * prov, const std::string & name)
{
	if (name == "Resource")
	{
		ResourceReferenceDefinition defXref;
		if (!prov->parse_object(defXref.GetLoader()))
			return false;

		std::auto_ptr<resource::Resource> camera_res(resource::Manager::create_resource(defXref.GetPath()));
		CameraDefinition def;
		def.SetSceneRoot(this->sceneRoot);

		if (!xml::StreamResource(camera_res.get()).load(&xml::Root(def.GetLoader(), "Camera")))
			THROW(GluckBadResource(__FUNCTION__, "load() failed", defXref.GetPath()));

		this->camera = def.ReleaseCamera();
		return true;
	}
	
	// Try parsing node as inline camera definition
	std::auto_ptr<node::Node> localCamera(node::Factory::create(this->sceneRoot, Atom(name), Atom("Camera")));
	if (prov->parse_object(localCamera.get()))
	{
		this->camera.reset(static_cast<node::Camera*>(localCamera.release()));
		return true;
	}

	return false;
}

ARELLO_GAME_NAMESPACE_DECL_END